package com.sf.innovate.hammer.game

import GameAudioManager
import android.os.Handler
import android.text.TextUtils
import android.util.Log
import com.google.mediapipe.tasks.vision.facelandmarker.FaceLandmarkerResult
import com.google.mediapipe.tasks.components.containers.Category
import com.kpa.demo.data.repository.MainRepository
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlin.random.Random

class GameSdk private constructor() {
  var mMainRepository:MainRepository = MainRepository()
  private val myJob = Job()
  private val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
    Log.i("请求错误信息", "${throwable.message}")
  }
  private val myScope = CoroutineScope(myJob + Dispatchers.Main + exceptionHandler)
  private var mCurrentState:GameState = GameState.IDLE;
  val gameAudioManager:GameAudioManager = GameAudioManager(ContextHolder.instance.mContext)
  var mHandler:Handler = Handler()
  private lateinit var mGameStateCallback:GameStateCallback;
  companion object {
    val instance: GameSdk by lazy { GameSdk() }
  }
  fun setCallback(callback:GameStateCallback){
    mGameStateCallback = callback;
  }
  suspend fun updateFaceLandmarkerResult(result: FaceLandmarkerResult?){
    if(mCurrentState == GameState.READY || mCurrentState == GameState.FINISHED){
      return
    }
    if(result != null){
      var categories: MutableList<Category?> = MutableList(50) { null }

      if (result != null && result.faceBlendshapes().isPresent) {
        val faceBlendshapes = result.faceBlendshapes().get()
//        Log.i("GameSdk", "faceBlendshapes:" + Gson().toJson(faceBlendshapes));
        val sortedCategories = faceBlendshapes[0].sortedByDescending { it.score() }
        val min = kotlin.math.min(sortedCategories.size, categories.size)
//        Log.i("GameSdk", "first:" + sortedCategories[0].categoryName() + ";socre = " + sortedCategories[0].score())
//        Log.i("GameSdk", "second:" + sortedCategories[1].categoryName() + ";socre = " + sortedCategories[1].score())
//        Log.i("GameSdk", "third:" + sortedCategories[2].categoryName() + ";socre = " + sortedCategories[2].score())
        for (i in 0 until min) {
          if(sortedCategories[i].categoryName().contains("eye") && sortedCategories[i].categoryName().contains("Left")){
            /*if(TextUtils.equals("eyeBlinkLeft", sortedCategories[i].categoryName())){
              myScope.launch {
                mMainRepository.bigEye()
              }
            }*/

            if(mCurrentState == GameState.COUNTDOWNING){
              mCurrentState = GameState.FINISHED
                 Log.i("GameSdk", "eyeLookUpLeft = " + sortedCategories[i].score())
              mHandler.removeCallbacksAndMessages(null)
              mHandler.postDelayed(Runnable {
                mCurrentState = GameState.IDLE
                mGameStateCallback.updateState(mCurrentState, "")
                }, 4000)
              val randomNumberInRange = Random.nextInt(0, 100)
              var isLeft = ((randomNumberInRange%2) == 0)
              Log.i("cxcx left", "${isLeft}")
              GlobalScope.launch  (CoroutineExceptionHandler { coroutineContext, throwable ->
                Log.d("GameSdk","response error: ${throwable.message}")
              }){
                if(isLeft){
                  // Move Left hand up.
                  Log.i("cxcx", "leftUp")
                   mMainRepository.leftUp()

                  //mMainRepository.rightDown()
                }else{
                  Log.i("cxcx", "leftDown")
                  // Move Right hand up.
                  //mMainRepository.rightUp()
                     mMainRepository.leftDown()
                }
              }
//              myScope.launch {
//
//              }
              if(isLeft){
                Log.i("GameSdk", "left success")
                mGameStateCallback.updateState(mCurrentState,"胜利" )
                gameAudioManager.playSound(R.raw.success)
                GlobalScope.launch (CoroutineExceptionHandler { coroutineContext, throwable ->
                  Log.d("GameSdk","response error: ${throwable.message}")
                }) {
                  mMainRepository.bigEye()
                }
              }else{
                Log.i("GameSdk", "left failed")
                mGameStateCallback.updateState(mCurrentState,"失败" )
                gameAudioManager.playSound(R.raw.failed)
                GlobalScope.launch (CoroutineExceptionHandler { coroutineContext, throwable ->
                  Log.d("GameSdk","response error: ${throwable.message}")
                }){
                  mMainRepository.minEye()
                }
              }
              break
            }

          }else if(sortedCategories[i].categoryName().contains("eye") && sortedCategories[i].categoryName().contains("Right")){
            /*if(TextUtils.equals("eyeBlinkRight", sortedCategories[i].categoryName())){
              myScope.launch {
                mMainRepository.minEye()
              }
            }*/
            if(mCurrentState == GameState.COUNTDOWNING){
              mCurrentState = GameState.FINISHED
                 Log.i("GameSdk", "eyeLookUpLeft = " + sortedCategories[i].score())
              mHandler.removeCallbacksAndMessages(null)
              mHandler.postDelayed(Runnable {
                mCurrentState = GameState.IDLE
                mGameStateCallback.updateState(mCurrentState, "")}, 4000)
              val randomNumberInRange = Random.nextInt(0, 100)
              var isRight = ((randomNumberInRange%2) == 1)
              myScope.launch (CoroutineExceptionHandler { coroutineContext, throwable ->
                Log.d("GameSdk","response error: ${throwable.message}")
              }) {
                if(isRight){
                  Log.i("cxcx", "rightUp")
                  mMainRepository.rightUp()
                  //mMainRepository.driverB60()
                }else{
                  mMainRepository.rightUp()
                  Log.i("cxcx", "rightUp")
                  //mMainRepository.driverA180()
                }
              }
              if(isRight){
                Log.i("GameSdk", "right success")
                mGameStateCallback.updateState(mCurrentState,"胜利" )
                gameAudioManager.playSound(R.raw.success)
                GlobalScope.launch  (CoroutineExceptionHandler { coroutineContext, throwable ->
                  Log.d("GameSdk","response error: ${throwable.message}")
                }){
                  mMainRepository.bigEye()
                }
              }else{
                Log.i("GameSdk", "right failed")
                mGameStateCallback.updateState(mCurrentState,"失败" )
                gameAudioManager.playSound(R.raw.failed)
                GlobalScope.launch  (CoroutineExceptionHandler { coroutineContext, throwable ->
                  Log.d("GameSdk","response error: ${throwable.message}")
                }){
                  mMainRepository.minEye()
                }
              }
              break
            }

          }else if(sortedCategories[i].categoryName().equals("mouthClose")){
//            Log.i("GameSdk", "mouthClose = " + sortedCategories[i].score())
            break
          }else if(sortedCategories[i].categoryName().equals("mouthRollUpper")){
            if(mCurrentState == GameState.IDLE){
              myScope.launch (CoroutineExceptionHandler { coroutineContext, throwable ->
                Log.d("GameSdk","response error: ${throwable.message}")
              }) {
                  mMainRepository.rightDown()
                  Thread.sleep(100)
                  mMainRepository.leftDown()
              }

              Log.i("GameSdk", "mouthRollUpper = " + sortedCategories[i].score())
              mCurrentState = GameState.READY
              mGameStateCallback.updateState(mCurrentState, "")
              gameAudioManager.playSound(R.raw.countdown)
              mHandler.postDelayed(Runnable {
                mCurrentState = GameState.COUNTDOWNING
                mHandler.postDelayed(Runnable { gameAudioManager.playSound(R.raw.rush) }, 1000)
                mHandler.postDelayed(Runnable { mCurrentState = GameState.IDLE
                  mGameStateCallback.updateState(mCurrentState, "")}, 10000)
              }, 3000)
            }

            break
          }else if(sortedCategories[i].categoryName().contains("mouthRollLower")){
            if(mCurrentState == GameState.COUNTDOWNING){
              Log.i("GameSdk", sortedCategories[i].categoryName() + " = " + sortedCategories[i].score())
              mCurrentState = GameState.FINISHED
              mGameStateCallback.updateState(mCurrentState, "")
            }

          }
        }
      }
    }

  }
}